/*
 *
 *  Copyright (C) 2010 Tal Eisenberg
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package tal.drivechain.matchers;

import tal.drivechain.chain.ChainNode;
import tal.drivechain.wildcard.Wildcard;
import tal.drivechain.wildcard.WildcardElement;

/**
 *
 * @author Main
 */
public class WildcardMatcher extends ValueMatcher {
    Wildcard wildcard;
    WildcardElement element;
    
    public WildcardMatcher(String elementClass) throws IllegalArgumentException {
        try {
            Class eClass = Class.forName(elementClass);
            element = (WildcardElement)eClass.newInstance();
        } catch (ClassNotFoundException ex) {
            throw new IllegalArgumentException("Wildcard element class not found: " + elementClass);
        } catch (InstantiationException ex) {
            throw new IllegalArgumentException("Wildcard element class could not be instantiated: " + elementClass);
        } catch (IllegalAccessException ex) {
            throw new IllegalArgumentException("Wildcard element class could not be instantiated (Illegal Access): " + elementClass);
        }
    }
    
    @Override
    protected void parseSpecial(String pattern) throws IllegalArgumentException {
        wildcard = Wildcard.parseDefinition(pattern, element);
    }

    @Override
    protected boolean matchSpecial(Object value, ChainNode context) throws IllegalArgumentException {
        return wildcard.matches(value, context);
    }

    @Override
    public String toString() {
        return wildcard.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof WildcardMatcher) {
            if (super.equals(obj)) return true;
            else {
                WildcardMatcher that = (WildcardMatcher)obj;
                
                return (this.element.getClass().equals(that.element.getClass()) && this.wildcard.equals(that.wildcard));
            }
        } else return false;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 23 * hash + (this.wildcard != null ? this.wildcard.hashCode() : 0);
        hash = 23 * hash + (this.element != null ? this.element.hashCode() : 0);
        return hash;
    }

}
